From 99087dd31bf6443bef2b8ab024422c2256c7f891 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Sun, 5 Oct 2014 20:21:57 -0700 Subject: [PATCH] Sort feature lists for fingerprint hashing Otherwise the order was nondeterministic likely due to some hash map along the way being used to deduplicate the set of features. Closes #665 --- src/cargo/ops/cargo_rustc/fingerprint.rs | 14 +++++---- tests/test_cargo_features.rs | 38 ++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 5 deletions(-) diff --git a/src/cargo/ops/cargo_rustc/fingerprint.rs b/src/cargo/ops/cargo_rustc/fingerprint.rs index f1840da87..6e7cff5f8 100644 --- a/src/cargo/ops/cargo_rustc/fingerprint.rs +++ b/src/cargo/ops/cargo_rustc/fingerprint.rs @@ -61,7 +61,7 @@ pub fn prepare_target(cx: &mut Context, pkg: &Package, target: &Target, doc || !path }; - debug!("fingerprint at: {}", new_loc.display()); + info!("fingerprint at: {}", new_loc.display()); // First bit of the freshness calculation, whether the dep-info file // indicates that the target is fresh. @@ -72,7 +72,11 @@ pub fn prepare_target(cx: &mut Context, pkg: &Package, target: &Target, // Second bit of the freshness calculation, whether rustc itself, the // target are fresh, and the enabled set of features are all fresh. let features = cx.resolve.features(pkg.get_package_id()); - let features = features.map(|s| s.iter().collect::>()); + let features = features.map(|s| { + let mut v = s.iter().collect::>(); + v.sort(); + v + }); let rustc_fingerprint = if use_pkg { mk_fingerprint(cx, &(target, try!(calculate_pkg_fingerprint(cx, pkg)), features)) @@ -144,7 +148,7 @@ pub fn prepare_build_cmd(cx: &mut Context, pkg: &Package) let old_loc = old.join("build"); let new_loc = new.join("build"); - debug!("fingerprint at: {}", new_loc.display()); + info!("fingerprint at: {}", new_loc.display()); let new_fingerprint = try!(calculate_build_cmd_fingerprint(cx, pkg)); let new_fingerprint = mk_fingerprint(cx, &new_fingerprint); @@ -244,10 +248,10 @@ fn calculate_target_fresh(pkg: &Package, dep_info: &Path) -> CargoResult { match fs::stat(&pkg.get_root().join(file)) { Ok(stat) if stat.modified <= mtime => {} Ok(stat) => { - debug!("stale: {} -- {} vs {}", file, stat.modified, mtime); + info!("stale: {} -- {} vs {}", file, stat.modified, mtime); return Ok(false) } - _ => { debug!("stale: {} -- missing", file); return Ok(false) } + _ => { info!("stale: {} -- missing", file); return Ok(false) } } } diff --git a/tests/test_cargo_features.rs b/tests/test_cargo_features.rs index 2f6f4d2ad..bad8fee8e 100644 --- a/tests/test_cargo_features.rs +++ b/tests/test_cargo_features.rs @@ -1,5 +1,6 @@ use support::{project, execs, cargo_dir}; use support::COMPILING; +use support::paths::PathExt; use hamcrest::assert_that; fn setup() { @@ -424,3 +425,40 @@ test!(union_features { {compiling} foo v0.0.1 ({dir}) ", compiling = COMPILING, dir = p.url()).as_slice())); }) + +test!(many_features_no_rebuilds { + let p = project("foo") + .file("Cargo.toml", r#" + [package] + name = "b" + version = "0.1.0" + authors = [] + + [dependencies.a] + path = "a" + features = ["fall"] + "#) + .file("src/main.rs", "fn main() {}") + .file("a/Cargo.toml", r#" + [package] + name = "a" + version = "0.1.0" + authors = [] + + [features] + ftest = [] + ftest2 = [] + fall = ["ftest", "ftest2"] + "#) + .file("a/src/lib.rs", ""); + + assert_that(p.cargo_process("build"), + execs().with_status(0).with_stdout(format!("\ +{compiling} a v0.1.0 ({dir}) +{compiling} b v0.1.0 ({dir}) +", compiling = COMPILING, dir = p.url()).as_slice())); + p.root().move_into_the_past().unwrap(); + + assert_that(p.process(cargo_dir().join("cargo")).arg("build"), + execs().with_status(0).with_stdout("")); +}) -- 2.30.2